package com.ruoyi.activity.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.activity.domain.ActHistoricActivityInstanceInfo;
import com.ruoyi.activity.domain.ActHistoricTaskInstanceInfo;
import com.ruoyi.activity.domain.ActTaskInfo;
import com.ruoyi.activity.domain.DescriptionInfo;
import com.ruoyi.activity.service.IActHistoryTaskService;
import com.ruoyi.activity.service.IActTaskService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ActTaskServiceImpl implements IActTaskService {
    @Autowired
    private TaskService taskService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    protected RepositoryService repositoryService;

    @Autowired
    protected RuntimeService runtimeService;
//
//    @Autowired
//    private FormService formService;

    @Autowired
    protected HistoryService historyService;

    @Autowired
    private IActHistoryTaskService actHistoryTaskService;

    @Override
    public ActTaskInfo getNodeById(String taskId) {
        Task tq = taskService.createTaskQuery().taskId(taskId).singleResult();

        return convertTask(tq);
    }

    /**
     * 根据任务ID获得任务实例
     *
     * @param taskId 任务ID
     * @return
     * @throws Exception
     */
    @Override
    public TaskEntity findTaskById(String taskId) throws Exception {
        TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new Exception("任务实例未找到!");
        }
        return task;
    }

    @Override
    public List<ActHistoricActivityInstanceInfo> getNodesByFlowId(String instanceId) {
        // 获取历史任务节点
        List<HistoricTaskInstance> hit = historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId)
                .list();
        Map<String, ActHistoricTaskInstanceInfo> historicTaskInfo = new HashMap<>();
        if (!CollectionUtils.isEmpty(hit)) {
            for (HistoricTaskInstance hai : hit) {
                ActHistoricTaskInstanceInfo taskInfo = actHistoryTaskService.convertHistoricTask(hai);
                historicTaskInfo.put(taskInfo.getId(), taskInfo);
            }
        }

        // 获取历史活动任务节点
        List<HistoricActivityInstance> historicActivityInstance = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId).orderByHistoricActivityInstanceEndTime().asc().list();
        List<ActHistoricActivityInstanceInfo> result = new ArrayList<>();
        for (HistoricActivityInstance hai : historicActivityInstance) {
            if(!"userTask".equals(hai.getActivityType())){
                continue;
            }
            ActHistoricActivityInstanceInfo ahainfo = new ActHistoricActivityInstanceInfo();
            ahainfo.setId(hai.getId());
            ahainfo.setActivityId(hai.getActivityId());
            ahainfo.setActivityName(hai.getActivityName());
            ahainfo.setActivityType(hai.getActivityType());
            ahainfo.setProcessDefinitionId(hai.getProcessDefinitionId());
            ahainfo.setProcessInstanceId(hai.getProcessInstanceId());
            ahainfo.setExecutionId(hai.getExecutionId());
            ahainfo.setTaskId(hai.getTaskId());
            ahainfo.setCalledProcessInstanceId(hai.getCalledProcessInstanceId());
            ahainfo.setAssignee(hai.getAssignee());
            ahainfo.setStartTime(hai.getStartTime());
            ahainfo.setEndTime(hai.getEndTime());
            ahainfo.setDurationInMillis(hai.getDurationInMillis());
            ahainfo.setDeleteReason(hai.getDeleteReason());
            ActHistoricTaskInstanceInfo taskInfo = historicTaskInfo.getOrDefault(hai.getTaskId(), null);
            if (taskInfo != null) {
                ahainfo.setAssigneeName(taskInfo.getAssigneeName());
                ahainfo.setAssigneeUserCompany(taskInfo.getAssigneeUserCompany());
                String description = taskInfo.getDescription();
                if(StringUtils.isNotBlank(description)){
                    try{
                        DescriptionInfo descriptionInfo = JSON.parseObject(description, DescriptionInfo.class);
                        ahainfo.setApprovalFileIds(StringUtils.isBlank(descriptionInfo.getApprovalFileIds())?"":descriptionInfo.getApprovalFileIds());
                        ahainfo.setApprovalStatus(descriptionInfo.getApprovalStatus());
                        ahainfo.setDescription(descriptionInfo.getRemarks());
                        ahainfo.setRejectType(descriptionInfo.getRejectType());
                        ahainfo.setCountersignature(descriptionInfo.getCountersignature());
                    } catch (Exception e){
                        e.fillInStackTrace();
                    }
                }
                ahainfo.setApplyUserId(taskInfo.getApplyUserId());
                ahainfo.setApplyUserName(taskInfo.getApplyUserName());
                ahainfo.setProcessVariables(taskInfo.getProcessVariables());
            }
            result.add(ahainfo);
        }
        return result;
    }

    private ActTaskInfo convertTask(Task task) {
        ActTaskInfo taskInfo = new ActTaskInfo();
        taskInfo.setTaskId(task.getId());
        taskInfo.setTaskName(task.getName());
        taskInfo.setAssignee(task.getAssignee());
        Long aLong = StringUtils.isNotBlank(task.getAssignee())?Long.parseLong(task.getAssignee()):null;
        SysUser assignUser = sysUserService.selectUserById(aLong);
        if(assignUser != null){
            taskInfo.setAssigneeName(assignUser.getUserName());
        }
        // 获取当前流程
        ProcessInstance instance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId()).singleResult();

        taskInfo.setProcessInstanceId(task.getProcessInstanceId());
        taskInfo.setActivityId(instance.getActivityId());
        taskInfo.setBusinessKey(instance.getBusinessKey());
        Long bLong = StringUtils.isNotBlank(instance.getStartUserId())?Long.parseLong(instance.getStartUserId()):null;
        SysUser applyUser = sysUserService.selectUserById(bLong);
        taskInfo.setApplyUserId(instance.getStartUserId());
        if(applyUser != null){
            taskInfo.setApplyUserName(applyUser.getUserName());
        }
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(task.getProcessDefinitionId()).singleResult();
        taskInfo.setProcessDefinitionId(task.getProcessDefinitionId());
        taskInfo.setProcessDefinitionKey(definition.getKey());
        taskInfo.setProcessDefinitionName(definition.getName());

        taskInfo.setStartTime(DateUtils.dateTime(task.getCreateTime()));
        taskInfo.setDescription(task.getDescription());

        taskInfo.setProcessVariables(taskService.getVariables(task.getId()));

//        FormData formData = formService.getTaskFormData(task.getId());
//        taskInfo.setFormKey(formData.getFormKey());
//        List<FormPropertyImpl> properties = new ArrayList<FormPropertyImpl>();
//        for (FormProperty property : formData.getFormProperties()) {
//            properties.add((FormPropertyImpl) property);
//        }
//        taskInfo.setFormProperties(properties);

        return taskInfo;
    }
}
